package com.erp.erp_servers.Department.imp;

import com.erp.erp_dao.Department.IDepartmentDAO;
import com.erp.erp_entitys.Account.AccountEntity;
import com.erp.erp_entitys.Department.DepartmentEntity;
import com.erp.erp_entitys.Department.DepartmentExample;
import com.erp.erp_entitys.Department.DepartmentTreeEntity;
import com.erp.erp_entitys.Dictionary.DictionaryEntity;
import com.erp.erp_entitys.User.UserEntity;
import com.erp.erp_entitys.UserGroup.UserGroupEntity;
import com.erp.erp_servers.Account.IAccountService;
import com.erp.erp_servers.Department.IDepartmentService;
import com.erp.erp_servers.Dictionary.IDictionary2Service;
import com.erp.erp_servers.User.IUserService;
import com.erp.erp_servers.UserGroup.IUserGroupService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;

/**
 * @ClassName ImpDepartmentService
 * @Description TODO
 * @Author songjizhen
 * @Date 2020-07-03 21:59
 * @Version 1.0
 */
@Service
public class ImpDepartmentService implements IDepartmentService {
    @Autowired
    IDepartmentDAO departmentDAO;
    @Autowired
    IUserService userService;
    @Autowired
    IDictionary2Service dictionary2Service;
    @Autowired
    IUserGroupService userGroupService;
    @Autowired
    IAccountService accountService;
    /**
     * 新增部门
     *
     * @param record
     * @return
     */
    @Override
    public int insertSelective(DepartmentEntity record) {
        return departmentDAO.insertSelective(record);
    }

    /**
     * 根据id查询部门
     *
     * @param id
     * @return
     */
    @Override
    public DepartmentEntity selectByPrimaryKey(Integer id) {
        return departmentDAO.selectByPrimaryKey(id);
    }

    /**
     * 根据id更新部门
     *
     * @param record
     * @return
     */
    @Override
    public int updateByPrimaryKeySelective(DepartmentEntity record) {
        return departmentDAO.updateByPrimaryKeySelective(record);
    }

    /**
     * 根据给定的条件查询部门
     *编码（code），名称（name），父节点（pid）
     * @param record
     * @return
     */
    @Override
    public List<DepartmentEntity> selectByExample(DepartmentEntity record) {
        DepartmentExample example=new DepartmentExample();
        DepartmentExample.Criteria criteria = example.createCriteria();
        if(record.getCode() !=null && record.getCode()!=""){
            criteria.andCodeEqualTo(record.getCode());
        }
        if(record.getName() !=null && record.getName() !=""){
            criteria.andNameEqualTo(record.getName());
        }
        if(record.getPid()!=null && record.getPid()!=""){
            criteria.andPidEqualTo(record.getPid());
        }
        if(record.getId() != null){
            criteria.andIdEqualTo(record.getId());
        }
        List<DepartmentEntity> departmentEntities = departmentDAO.selectByExample(example);
        return departmentEntities;
    }

    @Override
    public List<DepartmentEntity> selectByExample(DepartmentExample example) {
        return departmentDAO.selectByExample(example);
    }

    /**
     * 查询code是否得复
     *
     * @param code
     * @return
     */
    @Override
    public boolean getExitBycode(String code) {
        DepartmentExample example=new DepartmentExample();
        DepartmentExample.Criteria criteria = example.createCriteria();
        criteria.andCodeEqualTo(code);
        List<DepartmentEntity> departmentEntities = departmentDAO.selectByExample(example);
       // String tf=this.getPidBycode(code,departmentEntities);
        return  departmentEntities.size()==1;
    }

    /**
     * 根据code查询其所属公司
     *
     * @param code
     * @return
     */
    @Override
    public String getCompanentcodeBycode(String code) {
        DepartmentExample example=new DepartmentExample();
        DepartmentExample.Criteria criteria = example.createCriteria();
        List<DepartmentEntity> departmentEntities = departmentDAO.selectByExample(example);

        return this.getPidBycode(code,departmentEntities);
    }

    private String getPidBycode(String pid,List<DepartmentEntity> list){
        String companentcode="";
        for(int i=0;i<list.size();i++){
            DepartmentEntity de=list.get(i);
            if(de.getCode().equals(pid)&& !de.getCode().equals("0")){
                if(de.getPid().equals("0")){
                    companentcode=de.getCode();
                    break;
                }else{
                    companentcode=getPidBycode(de.getPid(),list);
                    break;
                }
            }
        }
        return companentcode;
    }

    /**
     * 获取组织机构树
     *
     * @return
     */
    @Override
    public DepartmentTreeEntity selectTree() {
        DepartmentExample example=new DepartmentExample();
        DepartmentExample.Criteria criteria = example.createCriteria();
        List<DepartmentEntity> departmentEntities = departmentDAO.selectByExample(example);
        Map<String,DepartmentEntity> map = new LinkedHashMap<>();
        for(DepartmentEntity de:departmentEntities){
            map.put(de.getCode(),de);
        }
        //拼装组织机构树
        DepartmentTreeEntity tree = this.getTree("0", map);
        return tree;
    }

    /**
     * 获取当前用户所属部门树
     * @param code 当前用户所属部门编码
     * @return 当前用户所属部门树
     */
    @Override
    public DepartmentTreeEntity getCurrentUserDepartmentTree(String code) {
        DepartmentExample example = new DepartmentExample();
        DepartmentExample.Criteria criteria = example.createCriteria();
        List<DepartmentEntity> departmentEntities = departmentDAO.selectByExample(example);
        Map<String, DepartmentEntity> map = new LinkedHashMap<>();
        for (DepartmentEntity de : departmentEntities) {
            map.put(de.getCode(), de);
        }
        //拼装组织机构树
        DepartmentTreeEntity tree = this.getTree(code, map);
        return tree;
    }

    /**
     * 根据id删除
     *
     * @param id
     * @return
     */
    @Override
    public int deleteByPrimaryKey(Integer id) {

        return departmentDAO.deleteByPrimaryKey(id);
    }

    /**
     *
     * @param code  用户组编码
     * @param model  模块
     * @param lx 类型
     * @return
     */
    @Override
    public DepartmentTreeEntity selectUserTree(String code, String model, String lx,String userCode) {
        //字典中取管理组配置信息
        List<DictionaryEntity> value= dictionary2Service.getValue(6, 55);
        //判断字典中是否有配置
        boolean tf=false;
        for (DictionaryEntity de:value){
            //用户组编码
            String name=de.getName();
            String obj=de.getCode();
            String[] split = obj.split(":");
            if(split.length <= 2){
                continue;
            }
            //用户编码
            String ucode=split[0];
            //模块
            String modelCode=split[1];
            //
            String lxCode=split[2];

            if(code.equals(name) && model.equals(modelCode) && userCode.equals(ucode) && lx.equals(lxCode)){
              tf=true;

                break;
            }
        }
        if(!tf){
            return null;
        }
        //取用户组信息
        UserGroupEntity uge=new UserGroupEntity();
        uge.setCode(code);
        List<UserGroupEntity> userGroupEntitys = userGroupService.selectByExample(uge);
        UserGroupEntity userGroupEntity=userGroupEntitys.get(0);
        //组内成员共享（1:共享；0:不共享）
        List<UserEntity> userList=new ArrayList<>();
        if(userGroupEntity.getIsShare()==1){
            userList = userService.selectUserByGroupCode(code);
        }else{
            userList.add(userService.selectUserByCode(userCode));
        }
        Map<String,UserEntity> userMap=new HashMap<>();
        List<String> departmentCode=new ArrayList<>();
        for(UserEntity ue:userList){
            departmentCode.add(ue.getDepartmentCode());
            userMap.put(ue.getCode(),ue);
        }
        DepartmentExample example=new DepartmentExample();
        DepartmentExample.Criteria criteria = example.createCriteria();
        criteria.andNameIn(departmentCode);
        List<DepartmentEntity> departmentEntities = departmentDAO.selectByExample(example);

        List<String> dcodeList=new ArrayList<>();
        Map<String,String> dcodeMap=new HashMap<>();
        for(DepartmentEntity de:departmentEntities){
            String[] paths=de.getPath().split("/");
            for(int i=0;i<paths.length;i++){
               // dcodeList.add(paths[i]);
                if(paths[i].equals("")){
                    continue;
                }
                dcodeMap.put(paths[i],"");
            }
        }
        for (Map.Entry<String,String> entry:dcodeMap.entrySet()   ) {
            dcodeList.add(entry.getKey());
        }

        List<DepartmentEntity> departmentEntities1 = departmentDAO.selectByCodeList(dcodeList);
        Map<String,DepartmentEntity> map=new HashMap<String,DepartmentEntity>();
        for(DepartmentEntity de:departmentEntities1){
            map.put(de.getCode(),de);
        }
        //拼装组织机构树
        DepartmentTreeEntity tree = this.getUserTree("0", map,userMap);
        return tree;


    }

    /**
     * 获取所有用户所管理的部门
     * @return 当前用户所管理的部门
     */
    @Override
    public DepartmentTreeEntity getAllDepartmentUser() {
        //获取所有用户信息
        List<UserEntity> userList = userService.getAllUser();
        //根据用户获取用户树
        DepartmentTreeEntity tree = getDepartmentTree(userList);

        return tree;
    }

    /**
     * 获取当前用户所管理的部门
     * @param userCode 当前用户编码
     * @return 当前用户所管理的部门
     */
    @Override
    public DepartmentTreeEntity getTheDepartmentManagedByTheCurrentUser(String userCode) {
        //初始化回参对象
        DepartmentTreeEntity tree = new DepartmentTreeEntity();
        if(StringUtils.isEmpty(userCode)){
            return tree;
        }

        //根据当前用户code获取用户信息
        UserEntity user = userService.selectUserByCode(userCode);
        //自定义角色组(多个以英文逗号隔开)
        String customerRole = user.getCustomerRole();
        //拆分成集合
        List<String> customerRoleList = new ArrayList<>();
        if(!StringUtils.isEmpty(customerRole)){
            customerRoleList = Arrays.asList(customerRole.split(","));
        }
        boolean isChild = false;
        //新的用户组
        List<UserEntity> newUsers = new ArrayList<>();

        //获取所有用户信息
        List<UserEntity> userList = userService.getAllUser();
        //根据用户获取用户树
        tree = getDepartmentTree(userList);
        if(null == tree || "admin".equals(user.getCode())){
            return tree;
        }
        //获取子部门人员信息
        getUserByTree(tree.getList(), newUsers, customerRoleList, user, isChild);
        if(customerRoleList.size() > 0){
            //获取自定义角色组对象信息
            List<UserEntity> userByUserCodeList = userService.getUserByUserCodeList(customerRoleList);

            //当前用户子部门人员 + 获取自定义角色人员
            newUsers.addAll(userByUserCodeList);
        }

        //获取最新的树
        DepartmentTreeEntity newTree = getDepartmentTree(newUsers);
        List<UserEntity> lu=new ArrayList<>();
        lu.add(user);
        newTree.setUsers(lu);
        return newTree;
    }

    /**
     * 获取当前用户所管理的部门(只包含在职人员)
     * @param userCode 当前用户编码
     * @return 当前用户所管理的部门(只包含在职人员)
     */
    @Override
    public DepartmentTreeEntity getServingOfficersDepartmentTree(String userCode) {
        //初始化回参对象
        DepartmentTreeEntity tree = new DepartmentTreeEntity();
        if(StringUtils.isEmpty(userCode)){
            return tree;
        }

        //根据当前用户code获取用户信息
        UserEntity user = userService.selectUserByCode(userCode);
        //自定义角色组(多个以英文逗号隔开)
        String customerRole = user.getCustomerRole();
        //拆分成集合
        List<String> customerRoleList = new ArrayList<>();
        if(!StringUtils.isEmpty(customerRole)){
            customerRoleList = Arrays.asList(customerRole.split(","));
        }
        boolean isChild = false;
        //新的用户组
        List<UserEntity> newUsers = new ArrayList<>();

        //获取所有用户信息
        List<UserEntity> userList = userService.getAllUser();
        //获取在职人员信息，剔除离职人员
        userList = getServingOfficers(userList);
        //根据用户获取用户树
        tree = getDepartmentTree(userList);
        if(null == tree || "admin".equals(user.getCode())){
            return tree;
        }
        //获取子部门人员信息
        getUserByTree(tree.getList(), newUsers, customerRoleList, user, isChild);
        if(customerRoleList.size() > 0){
            //获取自定义角色组对象信息
            List<UserEntity> userByUserCodeList = userService.getUserByUserCodeList(customerRoleList);
            //剔除离职人员
            userByUserCodeList = getServingOfficers(userByUserCodeList);

            //当前用户子部门人员 + 获取自定义角色人员
            newUsers.addAll(userByUserCodeList);
        }

        //获取最新的树
        DepartmentTreeEntity newTree = getDepartmentTree(newUsers);
        List<UserEntity> lu=new ArrayList<>();
        lu.add(user);
        newTree.setUsers(lu);
        return newTree;
    }

    /**
     * 获取在职人员信息
     * @param userList 所有用户
     * @return 在职人员信息
     */
    private List<UserEntity> getServingOfficers(List<UserEntity> userList) {
        if (CollectionUtils.isEmpty(userList)) {
            return userList;
        }
        List<UserEntity> newUserList = new ArrayList<>();
        for (UserEntity user : userList) {
            //获取帐号
            AccountEntity req = new AccountEntity();
            req.setUsercode(user.getCode());
            List<AccountEntity> accountList = accountService.getAccountList(req);
            if (!CollectionUtils.isEmpty(accountList)) {
                //在职
                newUserList.add(user);
            }
        }
        return newUserList;
    }

    /**
     * 通过用户编码获取该用户管理的所有用户编码(多个用户编码以英文逗号隔开)
     * @param userCode 指定用户编码
     * @return 该用户管理的所有用户编码
     */
    @Override
    public String getUserCodeByTheCurrentUser(String userCode) {
        if(StringUtils.isEmpty(userCode)){
            return userCode;
        }

        //根据当前用户code获取用户信息
        UserEntity user = userService.selectUserByCode(userCode);
        //自定义角色组(多个以英文逗号隔开)
        String customerRole = user.getCustomerRole();
        //拆分成集合
        List<String> customerRoleList = new ArrayList<>();
        if(!StringUtils.isEmpty(customerRole)){
            customerRoleList = Arrays.asList(customerRole.split(","));
        }

        //获取所有用户信息
        List<UserEntity> userList = userService.getAllUser();
        //根据用户获取用户树
        DepartmentTreeEntity tree = getDepartmentTree(userList);
        if(null == tree || "admin".equals(user.getCode())){
            return getUserCode(userList);
        }
        //新的用户组
        List<UserEntity> newUsers = new ArrayList<>();

        boolean isChild = false;
        //获取子部门人员信息
        getUserByTree(tree.getList(), newUsers, customerRoleList, user, isChild);

        if(customerRoleList.size() > 0){
            //获取自定义角色组对象信息
            List<UserEntity> userByUserCodeList = userService.getUserByUserCodeList(customerRoleList);

            //当前用户子部门人员 + 获取自定义角色人员
            newUsers.addAll(userByUserCodeList);
        }

        return getUserCode(newUsers);
    }

    /**
     * 获取用户编码
     * @param userList 用户对象集合
     * @return 用户编码
     */
    private String getUserCode(List<UserEntity> userList){
        String userCode = "";
        for(UserEntity userEntity : userList){
            if(StringUtils.isEmpty(userCode)){
                userCode += userEntity.getCode();
            }else {
                userCode += "," + userEntity.getCode();
            }
        }
        return userCode;
    }


    /**
     * 获取子部门人员信息
     * @param list 部门集合
     * @param newUsers 当前用户所能管理的用户
     * @param customerRoleList 自定义指定可管理的用户
     * @param user 当前用户
     */
    private void getUserByTree(List<DepartmentTreeEntity> list,
                               List<UserEntity> newUsers,
                               List<String> customerRoleList,
                               UserEntity user,
                               boolean isChild){
        if(CollectionUtils.isEmpty(list)){
            return;
        }
        for(DepartmentTreeEntity tree : list){
            //获取用户集合
            List<UserEntity> users = tree.getUsers();
            boolean newIsChild = false;
            if(!CollectionUtils.isEmpty(users)){
                boolean flag = false;
                //临时用户集合
                List<UserEntity> tempUsers = new ArrayList<>();
                for(UserEntity treeUser : users){
                    if(isChild){
                        tempUsers = users;
                        break;
                    } else if(customerRoleList.contains(treeUser.getCode())){
                        tempUsers.add(treeUser);
                    }else if(user.getCode().equals(treeUser.getCode())){
                        flag = true;
                        tempUsers.add(treeUser);
                    }
                }
                if(flag){
                    //当前用户在当前节点
                    if("是".equals(user.getMsn())){
                        //当前用户为管理层
                        newIsChild = true;
                        newUsers.addAll(users);
                    }else {
                        //普通用户
                        newUsers.addAll(tempUsers);
                    }
                }else {
                    //普通用户
                    newUsers.addAll(tempUsers);
                }
            }
            //获取子部门人员信息
            getUserByTree(tree.getList(), newUsers, customerRoleList, user, newIsChild);

        }

    }



    /**
     * 根据用户获取用户树
     * @param userList 用户集合
     * @return 用户树
     */
    private DepartmentTreeEntity getDepartmentTree(List<UserEntity> userList){
        Map<String, UserEntity> userMap = new HashMap<>();
        List<String> departmentCode = new ArrayList<>();
        for (UserEntity ue : userList) {
            departmentCode.add(ue.getDepartmentCode());
            userMap.put(ue.getCode(), ue);
        }
        DepartmentExample example = new DepartmentExample();
        DepartmentExample.Criteria criteria = example.createCriteria();
        criteria.andCodeIn(departmentCode);
        List<DepartmentEntity> departmentEntities = departmentDAO.selectByExample(example);

        List<String> dcodeList = new ArrayList<>();
        Map<String, String> dcodeMap = new HashMap<>();
        for (DepartmentEntity de : departmentEntities) {
            String[] paths = de.getPath().split("/");
            for (int i = 0; i < paths.length; i++) {
                if (paths[i].equals("")) {
                    continue;
                }
                dcodeMap.put(paths[i], "");
            }
        }
        for (Map.Entry<String, String> entry : dcodeMap.entrySet()) {
            dcodeList.add(entry.getKey());
        }

        List<DepartmentEntity> departmentEntities1 = departmentDAO.selectByCodeList(dcodeList);
        Map<String, DepartmentEntity> map = new HashMap<>();
        for (DepartmentEntity de : departmentEntities1) {
            map.put(de.getCode(), de);
        }
        //拼装组织机构树
        DepartmentTreeEntity tree = this.getUserTree("0", map, userMap);

        return tree;
    }

    public int getCount(String str,String key){
         if(str == null || key == null || "".equals(str.trim()) || "".equals(key.trim())){
             return 0;
         }
         int count = 0;
         int index = 0;
         while((index=str.indexOf(key,index))!=-1){
                 index = index+key.length();
                 count++;
         }
         return count;
    }


    private  DepartmentTreeEntity getUserTree(String code,Map<String,DepartmentEntity> map,Map<String,UserEntity> userMap){

        List<DepartmentTreeEntity> sublist=new ArrayList<DepartmentTreeEntity>();
        List<String> codes=new ArrayList<String>();//获取所有直接子节点code
        DepartmentEntity dt=map.get(code);
        DepartmentTreeEntity dte=this.conver(dt);
        for (Map.Entry<String, DepartmentEntity> entry : map.entrySet()) {
            if(dt.getCode().equals(entry.getValue().getPid())){
                codes.add(entry.getKey());
            }
            //System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
        }
        for(int i=0;i<codes.size();i++){
            sublist.add(this.getUserTree(map.get(codes.get(i)).getCode(),map,userMap));
        }
        List<UserEntity> uLi=new ArrayList<>();
        List<UserEntity> uList=userService.selectByExample(code);
        for(UserEntity ue:uList){
            if(userMap.get(ue.getCode() )!=null){
                uLi.add(userMap.get(ue.getCode()));
            }
        }
        
        dte.setUsers(uLi);
        dte.setList(sublist);


        return dte;
    }

    private  DepartmentTreeEntity getTree(String code,Map<String,DepartmentEntity> map){

        List<DepartmentTreeEntity> sublist=new ArrayList<DepartmentTreeEntity>();
        List<String> codes=new ArrayList<String>();//获取所有直接子节点code
        DepartmentEntity dt=map.get(code);
        DepartmentTreeEntity dte=this.conver(dt);
        for (Map.Entry<String, DepartmentEntity> entry : map.entrySet()) {
            if(dt.getCode().equals(entry.getValue().getPid())){
                codes.add(entry.getKey());
            }
            //System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
        }
       for(int i=0;i<codes.size();i++){
           sublist.add(this.getTree(map.get(codes.get(i)).getCode(),map));
       }
       //在最后一级挂接用户
       // if(codes.size()==0){
            dte.setUsers(userService.selectByExample(code));
        //}
       dte.setList(sublist);

        return dte;
    }
   /* private DepartmentTreeEntity2 conver(DepartmentTreeEntity dte){
        DepartmentTreeEntity2 dte2=new DepartmentTreeEntity2();
        dte2.setCode(dte.getCode());
        dte2.setCompanyCode(dte.getCompanyCode());
        dte2.setCode(dte.getCode());
        dte2.setCreateTime(dte.getCreateTime());
        dte2.setCreator(dte.getCreator());
        dte2.setDesc(dte.getDesc());
        dte2.setId(dte.getId());
        dte2.setName(dte.getName());
        dte2.setPid(dte.getPid());
        dte2.setUsers(dte.getUsers());
        dte2.setChildren(null);
        return  dte2;
    }*/
    private DepartmentTreeEntity conver(DepartmentEntity de){
        DepartmentTreeEntity dte=new DepartmentTreeEntity();
        dte.setCode(de.getCode());
        dte.setCompanyCode(de.getCompanyCode());
        dte.setCreateTime(de.getCreateTime());
        dte.setCreator(de.getCreator());
        dte.setDesc(de.getDesc());
        dte.setId(de.getId());
        dte.setName(de.getName());
        dte.setPid(de.getPid());
        return dte;
    }
}
